using System;
using System.Collections.Generic;
using System.Security.Cryptography;
using System.Text;
using Microsoft.Samples.ServiceHosting.StorageClient;
using Microsoft.WindowsAzure.ServiceRuntime;
using Ciripescu_WebRole.BL;
using Bitstar.YahooImport;
using Ciripescu_WebRole.Entities;

namespace Ciripescu_WebRole
{
    public enum EventLogName
    {
        Error,
        Warning,
        Information
    }
    public static class Utils
    {
        #region Public Methods

        public static string MD5Crypt(string pass)
        {
            MD5 md5 = new MD5CryptoServiceProvider();
            byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(pass));
            StringBuilder str = new StringBuilder();

            foreach (byte b in hash)
                str.Append(b.ToString("x2"));
            return str.ToString();
        }

        public static string ObfuscateEmail(string email)
        {
            string rot = rot13(email).Replace('@','|');
            while (rot.Contains("."))
                rot = rot.Replace('.', ':');
            return rot;
        }

        public static string DeObfuscateEmail(string email)
        {
            string rot = email.Replace('|', '@');
            while (rot.Contains(":"))
                rot = rot.Replace(':', '.');
            return rot13(rot);
        }

        public static string rot13(string str)
        {
            char x;
            string ret = string.Empty;
            for (int i = 0; i < str.Length; i++)
            {
                // If lowercase, add 13 and if it its gone past
                // z then subtract 26 so it gets that much deviation
                // from a instead of returning some wierd character
                if (((int)str[i] >= 65) && ((int)str[i] < 91))
                {
                    x = (char)((int)str[i] + 13);
                    if ((int)x >= 91) { x = (char)((int)x - 26); }
                }
                else
                {
                    // If uppercase, add 13 and if it its gone past
                    // Z then subtract 26 so it gets that much deviation
                    // from A instead of returning some wierd character
                    if (((int)str[i] >= 97) && ((int)str[i] < 123))
                    {
                        x = (char)((int)str[i] + 13);
                        if ((int)x >= 123) { x = (char)((int)x - 26); }
                    }
                    else
                    {
                        // If its a special character, ie not upper
                        // or lower case then just return as it is
                        x = str[i];
                    }
                }
                // Append the encrypted char to mystr
                ret += Convert.ToString(x);
            }
            return ret;
        } 

        /// <summary>
        /// Writes a message to role manager log.
        /// </summary>
        /// <param name="eventName"></param>
        /// <param name="message"></param>
        public static void WriteLog(EventLogName eventName,string message)
        {
            //RoleManager.WriteToLog(eventName.ToString(), message);

            switch (eventName)
            {
                
                case EventLogName.Error:
                    System.Diagnostics.Trace.TraceError(message,"Error");
                    break;
                case EventLogName.Warning:
                    System.Diagnostics.Trace.TraceWarning(message);
                    break;
                case EventLogName.Information:
                    System.Diagnostics.Trace.TraceInformation(message);
                    break;
            }

            // daca ii bai mare trimite-mi un mail sa vedem
            //if (eventName == EventLogName.Error)
            //{
            //    MailQueue q = new MailQueue();
            //    q.ReportCriticalError(message);
            //}
        }

        /// <summary>
        /// Returns a unique key used at password reset.
        /// </summary>
        /// <param name="val"></param>
        /// <returns></returns>
        public static string GetPasswordResetKey(string val)
        {
            // some algoritm I make the autologin key look a little more then just an md5 (48 chars instead of 32)
            // any hacker trying guess how this works will only get a headache
            return MD5Crypt(val + "bla bla") + MD5Crypt(val.ToUpper()).Substring(0, 16);
        }

        public static void ReportCriticalError(string message)
        {
            MailQueue q = new MailQueue();
            q.ReportCriticalError(message);            
        }

        public static MailContactList ValidateContactList(MailContactList list,string userName)
        {
            foreach (MailContact m in list)
            {
                if (string.IsNullOrEmpty(m.Name))
                    m.Name = m.MessengerID;
                if (string.IsNullOrEmpty(m.Email))
                    m.Email = m.MessengerID + "@yahoo.com";
            }

            MailContactList de_sters = new MailContactList();
            InviteManager im = new InviteManager();
            UserManager um = new UserManager();
            UrmarireManager urm = new UrmarireManager();
            for (int i = 0; i < list.Count - 1; i++)
            {
                // cauta duplicate
                for (int j = i + 1; j < list.Count; j++)
                {
                    if (list[i].Email == list[j].Email)
                    {
                        if (string.IsNullOrEmpty(list[i].Name)) de_sters.Add(list[i]);
                        else de_sters.Add(list[j]);
                    }
                }
            }
            foreach (MailContact sterge in de_sters)
                list.Remove(sterge);
            de_sters.Clear();

            MailQueue mq = new MailQueue();
            User currentUser = um.GetItem(userName);

            foreach (MailContact m in list)
            {
                // unii oameni se au si pe ei in lista si e jenant sa te adaugi singur :P
                if (currentUser.Email == m.Email)
                {
                    de_sters.Add(m);
                    continue;
                }
                // verifica daca userul este deja inregistrat
                User user = um.GetItemByEmail(m.Email);
                if (user != null)
                {
                    // adauga in lista de urmariti a userului curent
                    try
                    {
                        urm.Insert(new Urmarire(userName, user.GetUserName()));
                        mq.SendNewUrmaritorNotification(user.FullName, user.Email, currentUser.FullName, currentUser.Email, user.GetUserName(), currentUser.GetUserName());
                    }
                    catch (Exception ex)
                    {
                        // nu fa nimic pt ca inseamna doar ca userul era deja adaugat in lista
                    }
                    de_sters.Add(m);
                    continue;
                }

                // verifica daca userul nu a primit deja prea multe invitatii sau a zis explicit sa nu mai primeasca
                Invite inv = im.GetItem(m.Email);
                if (inv != null)
                {
                    if (inv.noMoreEmails)
                    {
                        de_sters.Add(m);
                        continue;
                    }
                }
                else im.Insert(new Invite(m.Email, m.Name, 0, new DateTime(1900, 1, 1)));
            }
            //im.Commit();
            foreach (MailContact sterge in de_sters)
                list.Remove(sterge);

            return list;
        }
        #endregion

        #region Public Properties
        #endregion

        #region Public Delegates
        #endregion

        #region Protected Methods
        #endregion

        #region Private Methods
        #endregion

        #region Protected Members
        #endregion

        #region Private Members
        #endregion
    }
}
